#pragma once
#include <chrono>
#include <boost/filesystem.hpp>
#include "arrow/log.h"
#include "server/config/config.h"
#include "state_machin_define.h"

namespace ArrowWebCodeView
{
namespace SessionMachine
{

class StateRecvPath : public StateBase
{
private:
    using Data = StateBase::Data;
    using StateEnum = StateBase::StateEnum;
    using Msg = StateBase::Msg;

public:
    StateRecvPath() {}

public:
    virtual ~StateRecvPath() {}

    /**
     * @description: 初始化 创建状态的时候调用一次
     * @param {AreaMachineData&} data
     * @return {*}
     */
    virtual void Init(const Data& data)
    {
    }

    /**
     * @description: 当从其他状态迁移到当前状态调用
     * @param {AreaMachineData*} pData
     * @return {*}
     */
    virtual void Start(Data* pData)
    {
    }

    /**
     * @description: 处理消息
     * @param {Data*} pData
     * @param {Msg} msg
     * @return {*}
     */
    virtual StateEnum HandleMsg(Data* pData, Msg msg, const std::string& strMsg, std::string& strResult)
    {
        if(!(msg == Msg::Folder || msg == Msg::File || msg == Msg::Path))
            return StateEnum::RecvPath;

        if(strMsg.empty())
        {
            return m_pContext->HandleMsg(Msg::Path, AppConfig::Instance()->DefalutFolder(), strResult);
        }
        
        boost::filesystem::path path(strMsg);
        if(!boost::filesystem::exists(path))
        {
            ARROW_LOG_WARN_FMT("path not exist: %s", strMsg.c_str());
            return StateEnum::RecvPath;
        }

        if(boost::filesystem::is_directory(path))
        {
            m_pContext->ChangeState(StateEnum::SendPathList);
            return m_pContext->HandleMsg(Msg::Folder, strMsg, strResult);
        }

        if(boost::filesystem::is_regular_file(path))
        {
            m_pContext->ChangeState(StateEnum::SendFileData);
            return m_pContext->HandleMsg(Msg::File, strMsg, strResult);
        }

        return StateEnum::RecvPath;
    }

    /**
     * @description: 处理定时消息
     * @param {AreaMachineData*} pData
     * @return {*}
     */    
    virtual StateEnum Timer(Data* pData)
    {
        return State();
    }

    /**
     * @description: 当前状态
     * @return {*}
     */
    virtual StateEnum State()
    {
        return StateEnum::RecvPath;
    }

    virtual void Context(ContextType* pContext)
    {
        m_pContext = pContext;
    }

private:
    ContextType* m_pContext = nullptr;

};
}
}